home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* Ico2bmp - Small utility program, which reads a icon file (.ico), extracts*/
- /* the color part of the icon, and generates a bitmap file (.bmp). */
- /* */
- /* Author: Niels Erik Holm, ICL DATA A/S, Copenhagen Denmark, neh@rci.dk */
- /* No copyrights apply, no Warranty */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <windows.h>
- #include <stdio.h>
- #include <string.h>
- #include <process.h>
- #include <dos.h>
-
- char * Version = "Ico2bmp v1.0 - Extracts color bitmap from icon file - Author: neh@rci.dk";
-
- typedef struct {
- WORD icoReserved; /* Reserved, must be set to 0 */
- WORD icoResourceType; /* Resource type, 1 for icon resources */
- WORD icoResourceCount; /* Number of images in the file */
- } IconFileHeader;
-
- typedef struct {
- BYTE Width; /* Width in pixels */
- BYTE Height; /* Height in pixels */
- BYTE ColorCount; /* Number of colors */
- BYTE Reserved1;
- WORD Reserved2;
- WORD Reserved3;
- DWORD icoDIBSize; /* Size in bytes of the pixel array */
- DWORD icoDIBOffset; /* Offset in bytes from beginning of file */
- /* to pixel array. */
- } IconRscDir;
-
- typedef struct {
- IconFileHeader IHead; /* Icon file header */
- IconRscDir IDir; /* Icon resource directory */
- BYTE IBits[1000];
- } IconFile;
-
- BITMAPFILEHEADER bmFH;
- BITMAPINFOHEADER bmIH;
- RGBQUAD bmCol[16];
-
- unsigned char Idata[1000];
- unsigned char Odata[1000];
-
- int opterr = 1;
- int optind = 1;
- int optopt;
- char * optarg;
-
- struct find_t fb;
- int MoreFiles;
-
- static int getopt(int,char **,char *);
- static int ProcessFile(char *,char *);
- static void ManipulateBits(BYTE *,BYTE *,int);
- static void usage(void);
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int opt,attr;
- char * Fptr;
- char InFileSpec[64];
- char FirstName[64];
- char InName[64];
- char OutName[64];
-
- InFileSpec[0] = 0;
- attr = 0;
-
- while ((opt = getopt(argc,argv,"hi:")) != -1)
- switch (opt) {
- case 'h':
- usage();
- exit(1);
- break;
- case 'i':
- strcpy(InFileSpec,optarg);
- break;
- }
-
- if (InFileSpec[0] == 0) {
- usage();
- exit(1);
- }
-
- if ((Fptr = strchr(InFileSpec,'.')) == NULL)
- strcat(InFileSpec,".ico");
-
- MoreFiles = (_dos_findfirst(InFileSpec,attr,&fb) == 0);
- if (!MoreFiles) {
- fprintf (stderr,"No files matching %s\n",InFileSpec);
- exit(1);
- }
-
- strcpy(FirstName,fb.name);
-
- while (MoreFiles) {
-
- strcpy(InName,fb.name);
- strcpy(OutName,InName);
- Fptr = strchr(OutName,'.');
- strcpy(Fptr,".bmp");
-
- (void) ProcessFile(InName,OutName);
-
- MoreFiles = ((_dos_findnext(&fb)==0) && (strcmp(FirstName,fb.name)!=0));
- }
- }
-
- static int ProcessFile(char * InFileName,char * OutFileName)
- {
- FILE * Ifile;
- FILE * Ofile;
- IconRscDir* pIRD;
- BITMAPINFOHEADER * pBMIH;
- RGBQUAD * pRGB;
- BYTE * pColorData;
- BYTE * pMonoData;
- int i,j,Ino,Cno,DataNo,ColorTabSize,BitMapSize,Pixels,BitsPerPixel;
- char * Iptr;
- unsigned char * Bptr;
-
-
- if ((Ifile = fopen(InFileName,"rb")) == NULL) {
- fprintf (stderr,"Error opening input file %s\n",InFileName);
- return(0);
- }
- fread (Idata,1,sizeof(Idata),Ifile);
- fclose(Ifile);
-
- if ((Ofile = fopen(OutFileName,"wb")) == NULL) {
- fprintf (stderr,"Error opening output file %s\n",OutFileName);
- return(0);
- }
-
- fprintf (stdout,"Processing %s -> %s",InFileName,OutFileName);
-
- Iptr = Idata;
-
- if (((IconFileHeader *)Iptr)->icoReserved != 0) {
- fprintf (stderr,"\nSorry! Invalid icon file.\n");
- return(0);
- }
-
- Ino = ((IconFileHeader *)Iptr)->icoResourceCount;
- if (Ino != 1) {
- fprintf (stderr,"\nSorry! Ico2bmp can only handle icon file with one icons.\n");
- return(0);
- }
-
- Iptr += sizeof(IconFileHeader);
- pIRD = (IconRscDir *)Iptr;
- pBMIH= (BITMAPINFOHEADER *)(Idata + pIRD->icoDIBOffset);
- pRGB = (RGBQUAD *)((BYTE *)pBMIH+sizeof(BITMAPINFOHEADER));
- ColorTabSize = pIRD->ColorCount*sizeof(RGBQUAD);
- pColorData = (BYTE *)((BYTE *)pRGB+ColorTabSize);
- BitsPerPixel = pBMIH->biBitCount;
- Pixels = pIRD->Width*pIRD->Height*BitsPerPixel;
- BitMapSize = Pixels/8;
- pMonoData = (BYTE *)(pColorData + BitMapSize);
-
- Cno=pBMIH->biBitCount;
- if (Cno==1)
- Cno=2;
- else if (Cno==4)
- Cno=16;
- else if (Cno==8)
- Cno=256;
- else if (Cno==24)
- Cno=0;
-
- if (Cno != 16) {
- fprintf (stderr,"\nSorry! Ico2bmp can only handle 16 color icons\n");
- return(0);
- }
-
- bmFH.bfType = 'B' | 'M'<<8;
- bmFH.bfSize = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize+BitMapSize;
-
- bmFH.bfOffBits = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize;
-
- bmIH.biSize = pBMIH->biSize;
- bmIH.biWidth = pBMIH->biWidth;
- bmIH.biHeight = pBMIH->biHeight/2;
- bmIH.biPlanes = pBMIH->biPlanes;
- bmIH.biBitCount = pBMIH->biBitCount;
- bmIH.biCompression = pBMIH->biCompression;
- bmIH.biSizeImage = BitMapSize;
- bmIH.biXPelsPerMeter = pBMIH->biXPelsPerMeter;
- bmIH.biYPelsPerMeter = pBMIH->biYPelsPerMeter;
- bmIH.biClrUsed = pBMIH->biClrUsed;
- bmIH.biClrImportant = Cno;
-
- for (i=0;i<Cno;i++)
- bmCol[i] = *((RGBQUAD*)((BYTE*)pRGB + i*sizeof(RGBQUAD)));
-
- ManipulateBits(pColorData,pMonoData,Pixels);
-
- memcpy(Odata,pColorData,BitMapSize);
-
- fwrite(&bmFH,sizeof(bmFH),1,Ofile);
- fwrite(&bmIH,sizeof(bmIH),1,Ofile);
- fwrite(&bmCol[0],ColorTabSize,1,Ofile);
- fwrite(&Odata[0],BitMapSize,1,Ofile);
-
- fclose(Ofile);
-
- fprintf (stdout,"\n");
-
- return(1);
- }
-
- static void ManipulateBits(BYTE * pColorData,BYTE * pMonoData,int pixels)
- /* Works only on 16 color bitmaps */
- {
- register int i,MonoBits,XorMask,j;
- register BYTE * pMD;
-
- pMD = pMonoData;
- MonoBits = *pMD;
- j=0;
-
- for (i=0;i<pixels/2;i++) {
- if (MonoBits & 0x80)
- *(pColorData+i) |= 0xF0;
- MonoBits <<= 1;
- j++;
- if (MonoBits & 0x80)
- *(pColorData+i) |= 0x0F;
- MonoBits <<= 1;
- j++;
- if (j==8) {
- ++pMD;
- MonoBits = *pMD;
- j=0;
- }
- }
- }
-
- static void usage()
- {
- fprintf (stdout,"%s\n",Version);
- fprintf (stdout,"Usage: ico2bmp -i <inputfile> [-h]\n");
- fprintf (stdout,"\n");
- fprintf (stdout," -h: Display this help\n");
- fprintf (stdout," -i: Name of input file. If no extension is specified .ico is used.\n");
- fprintf (stdout," Wildcards are allowed. Ex. -i *.ico\n");
- }
-
- #define index strchr
-
- #define ERR(s, c) if(opterr){\
- extern int write();\
- char errbuf[2];\
- errbuf[0] = c; errbuf[1] = '\n';\
- (void) fprintf(stderr, argv[0], (unsigned)strlen(argv[0]));\
- (void) fprintf(stderr, s, (unsigned)strlen(s));\
- (void) fprintf(stderr, errbuf, 2);}
-
- static int getopt(int argc, char ** argv, char * opts)
- {
- static int sp = 1;
- register int c;
- register char *cp;
-
- if(sp == 1)
- if(optind >= argc ||
- argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(-1);
- else if(strcmp(argv[optind], "--") == 0) {
- optind++;
- return(-1);
- }
- optopt = c = argv[optind][sp];
- if(c == ':' || (cp=index(opts, c)) == 0) {
- ERR(": illegal option -- ", c);
- if(argv[optind][++sp] == '\0') {
- optind++;
- sp = 1;
- }
- return('?');
- }
- if(*++cp == ':') {
- if(argv[optind][sp+1] != '\0')
- optarg = &argv[optind++][sp+1];
- else if(++optind >= argc) {
- ERR(": option requires an argument -- ", c);
- sp = 1;
- return('?');
- } else
- optarg = argv[optind++];
- sp = 1;
- } else {
- if(argv[optind][++sp] == '\0') {
- sp = 1;
- optind++;
- }
- optarg = 0;
- }
- return(c);
- }
-